#pragma once
#include <string>
#include <map>
#include "interfaces.h"
#include "StringLibraries.h"
#include <boost\thread\mutex.hpp>
#include <tchar.h>
namespace re{
namespace string{


class StringHandle
{
public:
	StringHandle() : m_id(0) {}
	StringHandle(const StringHandle& handle);
	StringHandle(const unsigned int id);
	StringHandle(const std::string & str);
	StringHandle(const char * const str);
	StringHandle(const std::wstring & str);
	StringHandle(const TCHAR * const str);
	~StringHandle();

	StringHandle& operator=(const StringHandle& handle);
	bool operator<(const StringHandle& handle) const;
	bool operator==(const StringHandle& handle) const;

	const std::string& GetString();
	bool SetString(const std::string & str);
	std::string  MakeString();
	const char * const c_str() const;
private:
	unsigned int m_id;

};
typedef std::map<unsigned int, std::pair<unsigned int, std::string>> IdMap;
#ifdef HIGH_SPEED_STRINGS
typedef std::map<std::string, IdMap::iterator> StringMap;
#endif
class StringTable
{
public:
	StringTable() : m_free_ids(0), m_last_id(0) {}
	~StringTable() {}
protected:
	friend StringHandle;
	unsigned int GetIdByString(const std::string& str);
	unsigned int ValidateId(const unsigned int id);
	const std::string * const GetStringById(const unsigned int id);

	void AddReference(const unsigned int id);
	void SubReference(const unsigned int id);

	void ReleaseStrings();

	static StringTable* const Get();
private:
	unsigned int get_a_new_id();
	mutable boost::mutex m_mutex;
	IdMap m_IdMap;
	unsigned int m_free_ids;
	unsigned int m_last_id;
#ifdef HIGH_SPEED_STRINGS
	StringMap m_StringMap;
#endif
};



}
}